#include <QCefContext.h>
#include <auth/auth.h>
#include <bonddict/IBondDict.h>
#include <core/DevCfg.h>
#include <core/FileSys.h>
#include <core/StyleMgr.h>
#include <core/core.h>
#include <guiframe/IApplication.h>
#include <qbkernel/include/qb_base.h>
#include <qbtools/message/RequestNotifier.h>

#include <QApplication>
#include <QDir>
#include <QLibrary>
#include <QProcess>

using namespace qb;

int main(int argc, char* argv[]) {
#if (QT_VERSION <= QT_VERSION_CHECK(6, 0, 0))
  // For off-screen rendering, Qt::AA_EnableHighDpiScaling must be enabled. If
  // not, then all devicePixelRatio methods will always return 1.0, so CEF will
  // not scale the web content NOET: There is bugs in Qt 6.2.4, the HighDpi
  // doesn't work
  QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
  QApplication::setHighDpiScaleFactorRoundingPolicy(
      Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
#endif
  IApplication* app = getAppInstance(argc, argv);
  logInfo("Main", "用户配置文件夹%s",
          FileSys::instance()->userCfgDir().toStdString().c_str());

  // build QCefConfig
  QCefConfig config;
  // set user agent
  config.setUserAgent("");
  // set log level
  config.setLogLevel(QCefConfig::LOGSEVERITY_DEFAULT);
  // set JSBridge object name (default value is QCefViewClient)
  config.setBridgeObjectName("CallBridge");
  // port for remote debugging (default is 0 and means to disable remote
  // debugging)
  config.setRemoteDebuggingPort(9000);
  // set background color for all browsers
  // (QCefSetting.setBackgroundColor will overwrite this value for specified
  // browser instance)
  config.setBackgroundColor(Qt::lightGray);

  // WindowlessRenderingEnabled is set to true by default,
  // set to false to disable the OSR mode
  config.setWindowlessRenderingEnabled(true);
#ifndef Q_OS_WINDOWS
  // set user_data_path, because crash_reporter.cfg need it.
  config.setUserDataPath(FileSys::instance()->dataDir() + "/Crashpad/");
#endif
  // add command line0 args, you can any cef supported switches or parameters
  config.addCommandLineSwitch("use-mock-keychain");
  // config.addCommandLineSwitch("disable-gpu");
  // config.addCommandLineSwitch("enable-media-stream");
  // config.addCommandLineSwitch("allow-file-access-from-files");
  // config.addCommandLineSwitch("disable-spell-checking");
  // config.addCommandLineSwitch("disable-site-isolation-trials");
  // config.addCommandLineSwitch("enable-aggressive-domstorage-flushing");
  config.addCommandLineSwitchWithValue("renderer-process-limit", "1");
  // allow remote debugging
  config.addCommandLineSwitchWithValue("remote-allow-origins", "*");
  // config.addCommandLineSwitchWithValue("disable-features",
  // "BlinkGenPropertyTrees,TranslateUI,site-per-process");

  config.addCommandLineSwitchWithValue(
      "log-file", FileSys::instance()->dataDir() + "/browser.log");

#if defined(Q_OS_MACOS) && defined(QT_DEBUG)
  // cef bugs on macOS debug build
  config.setCachePath(QDir::tempPath());
#else
  config.setCachePath(FileSys::instance()->dataDir() + "/Cache/");
#endif

#ifdef Q_OS_LINUX
  {
    QDir cefDir = QApplication::applicationDirPath() + "/../cef/resources";
    config.setResourceDirectoryPath(cefDir.absolutePath());
    QDir subProcess =
        QApplication::applicationDirPath() + "/../cef/CefViewWing";
    config.setBrowserSubProcessPath(subProcess.absolutePath());
    QDir LocalesDir =
        QApplication::applicationDirPath() + "/../cef/resources/locales";
    config.setLocalesDirectoryPath(LocalesDir.absolutePath());

    logInfo("Main", "cefDir: %s", cefDir.absolutePath().toStdString().c_str());
    logInfo("Main", "subProcess: %s",
            subProcess.absolutePath().toStdString().c_str());
  }
#endif

  qbBase* qb = nullptr;
  {
    // create QCefContext instance with config,
    // the lifecycle of cefContext must be the same as QApplication instance
    QCefContext cefContext(qApp, argc, argv, &config);

    bool runOne = false;
    DevCfg::instance().getBoolean("RunOnce", runOne, true);
    QString strPath = QApplication::applicationDirPath();

    StyleMgr::instance();

    qb = qbBase::getInterface();
    qb->init(strPath.toUtf8().toStdString().c_str());
    getDictUpdate()->init();
    registSpecificMsgProcessor();

    log_info("Logining Start");
    if (!authlogin(getDictUpdate())) {
      return 0;
    }

    app->run();
  }
  releaseApp();

  getDictUpdate()->uninit();
  qb->terminate();

  return 0;
}
